package autotreno;

import interfaccia.IAutotreno;
import interfaccia.IBase;
import interfaccia.IDitta;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Autotreno {
	private static final String HOST = "localhost";
	private String nome;
	private String nomeBasePartenza;
	private IBase basePartenza;
	private IDitta ditta;
	private AutotrenoImpl autotrenoImpl;
	private TViaggio viaggio;

	public Autotreno(String nomeAutotreno, String base) {
		nome=nomeAutotreno;
		nomeBasePartenza=base;
		try {
			autotrenoImpl=new AutotrenoImpl();
			autotrenoImpl.run();
		} catch (RemoteException e) {
			System.out.println("Errori nel server remoto alla creazione di AutotrenoImpl()");
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected void chiudiAutotreno()
	{
		System.exit(0);
	}
	
	class AutotrenoImpl extends UnicastRemoteObject implements IAutotreno {
		private static final long serialVersionUID = 1L;
		public AutotrenoImpl()throws RemoteException {}
		public void run() throws Exception {
			TRegistrazioneAutotreno thread=new TRegistrazioneAutotreno(ditta,this,nomeBasePartenza);
			thread.start();
		}
		@Override
		public String nomeAutotreno() throws RemoteException {
			return nome;
		}
		@Override
		public void impostaViaggio(IBase mittente ,IBase destinazione) throws RemoteException {
			viaggio=new TViaggio(mittente, destinazione, this,ditta);
			viaggio.start();
		}
		@Override
		public void interrompiAttivita() throws RemoteException {
			if(viaggio!=null){
				if(!viaggio.isAlive())
					return;
				else
					viaggio.interrupt();
				if(viaggio.isInterrupted())
					System.out.println("INTERROTTO -Autotreno in viaggio");
			}
			
		}
		@Override
		public void quit() throws RemoteException {
			chiudiAutotreno();
		}
		@Override
		public void impostaBase(IBase base,IAutotreno treno) throws RemoteException {
			basePartenza = base;
			basePartenza.parcheggia(treno);
		}

	}
	//-----------------------------------
	class TRegistrazioneAutotreno extends Thread {
		IAutotreno treno;
		String nomeBaseIniziale;
		/*
		 * costruttore della classe TRegistrazioneAutotreno
		 */
		public TRegistrazioneAutotreno(IDitta dittaref,IAutotreno autotreno, String base) {
			setDaemon(true);
			//ditta=dittaref;
			treno=autotreno;
			nomeBaseIniziale=base;

		}
		/*
		 * thread del tutto inutile dovrebbe essere una semplicemente una funzione
		 */
		public void run() {
			
				try {
	
					ditta = (IDitta) Naming.lookup("rmi://"+HOST+"/Ditta");
					ditta.registrazioneAutotreno(treno, nomeBasePartenza);

					
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (NotBoundException e) {
					e.printStackTrace();
				}
			
		}
	}// -------- Class 

	
	
	class TViaggio extends Thread {
		IAutotreno autotreno;
		IBase base;
		IDitta ditta;
		IBase mittente;
		/*
		 * costruttore della classe TGestioneOrdini
		 */
		public TViaggio(IBase mittenteref,IBase destinazione,IAutotreno autotrenoref,IDitta dittaref) {
			base=destinazione;
			autotreno=autotrenoref;
			ditta=dittaref;
			mittente =mittenteref;
		}
		/*
		 * override del metodo run della classe Thread.
		 */
		public void run() {
			try {
				ditta.comunicaPartenza(autotreno);
				int secondi=5;
				System.out.println("Autotreno "+ nome + " in viaggio");
				while(secondi>0){
					Thread.sleep(1000);
					System.out.println("Autotreno "+ nome + " in viaggio - sleeping");
					secondi--;
					if (Thread.interrupted()) {
					    throw new InterruptedException();
					}
				}

				try {
					//System.out.println("Autocarro arrivato, provo a parcheggiare");
					base.parcheggia(autotreno);
					//System.out.println("Autocarro arrivato, provo a parlare con la ditta");
					ditta.trasportoCompletato(mittente, autotreno, base);
					System.out.println("Autotreno arrivato");

				} catch (RemoteException e) {
					System.out.println("L'autotreno " + nome + " non ha trovato la base di arrivo. Torna alla base di partenza.");
					mittente.parcheggia(autotreno);
					ditta.trasportoCompletato(mittente, autotreno, mittente);
					ditta.controllaPresenzaBasi();
					//e.printStackTrace();
				}
			} catch (InterruptedException e) {
				System.out.println("Viaggio dell'autotreno "+ nome + " interrotto e gestito correttamente");
				try {
					ditta.riuscitaChiusura(autotreno.nomeAutotreno());
					System.exit(0);
				} catch (RemoteException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				return;
			} catch (RemoteException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			finally{
			}
		}
	}// -------- Class 
}
